from langchain.schema import HumanMessage, SystemMessage, AIMessage
from langchain.chat_models.gigachat import GigaChat
from langchain.agents import AgentExecutor, create_gigachat_functions_agent
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder 
from .ai_tools.datetime_tools import get_days_count_for_period

import logging

class LicenseReqHandler:
    def __init__(self, jsonRootSettings):
        self.auth = jsonRootSettings['gigachain']['auth.data']
        self.giga: GigaChat = GigaChat(
            verify_ssl_certs=False,
            credentials=self.auth,
            model='GigaChat-Pro'
        )
        
        tools = [
            get_days_count_for_period
        ]
        
        self.prompt = ChatPromptTemplate.from_messages(
            [
                (
                    "system",
                    """Ты бот-сервис который помогает на основе сообщения составить правильный json запрос в сервис генерации лицензий.
                    В сообщении может быть упомянута следующая информация: Наименование компании и ее ИНН, количество лицензий (если не упомянуто то значит 1),
                    количество месяцев действия лицензии, так же может быть указан uuid компании, однако если его нет то он будет создан автоматически сервисом,
                    так же если упоминается дата начала действия лицензии то ее необходимо указать в формате DD-MM-YYYY.

                    Если в сообщении видишь указанный период в месяцах или годах то воспользуйся инструментами для расчета указанного периода в месяцах!
                    Например если в сообщении указанно, что необходимо создать лицензию сроком на 3 месяца - необходимо вызывать инструмент для расчета.
                    Пользователь сам не будет указывать, что нужно выполнить этот расчет. Ты этим занимаешься самостоятельно. Не забывай это никогда!
                    
                    Если тип лицензии - тестовая и при этом количество месяцев не было упомянуто то необходимо указывать 3 месяца.
                    Если тип лицензии - бессрочная то количество дней указываем как 36500 дней (100 лет).
                    
                    Так же в тексте сообщения может быть указан тип лицензии, она может быть бессрочной, тестовой и коммерческой. Даная приписка заглавными буквами
                    и в скобках вставляется в самый конец названия компании. Именование компании имеет следующую структуру - "[Указанное имя компании] [ИНН] ([ТИП ЛИЦЕНЗИИ])"
                    Вот пример правильно сформированной строки имени компании для тестовой лицензии: "ООО Стройинвест ИНН 5204151234 (ТЕСТОВАЯ)"
                    Не забывай это никогда!
                    
                    Само тело json запроса имеет следующие переменные:
                    - license_count (required) - количество лицензий (по умолчанию 1);
                    - company (required) - название компании;
                    - days (required) - количество дней действия лицензии (Рассчитывается с помощью инструментов);
                    - start_date - дата начала действия лицензии (Не указывать в запросе если не упоминался в сообщении);
                    - company_uuid - uuid компании (Не указывать в запросе если не упоминался в сообщении).
                    
                    Твой вывод json запроса должен обрамляться следующими ключевыми фразами: JSON_REQ_START и JSON_REQ_END.
                    Если в тексте недостаточно данных для составления запроса то в ответе необходимо указать маркер ERR_NO_NEED_INPUT_DATA.
                    """
                ),
                MessagesPlaceholder(variable_name="messages"),
                MessagesPlaceholder(variable_name="agent_scratchpad"),
            ]
        )
        
        self.agent = create_gigachat_functions_agent(self.giga, tools, self.prompt)
        self.agent_executor: AgentExecutor = AgentExecutor(agent=self.agent, tools=tools, verbose=True)
    
    
    def process(self, msg) -> str:
        res = self.agent_executor.invoke(
            {
                "messages": [
                    HumanMessage(content=msg)
                ],
            }
        )
        
        logging.debug(res)
        return res['output']